package com.pig4cloud.pig.juhe.api.util;

import cn.hutool.core.lang.UUID;
import com.alibaba.fastjson.JSON;
import com.pig4cloud.pig.common.core.util.DateUtil;
import net.dongliu.apk.parser.ApkFile;
import net.dongliu.apk.parser.bean.ApkMeta;

import java.io.BufferedReader;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/**
 * @author yuwenfeng
 * @description: 读取apk信息工具类
 * @date 2021/10/8 15:21
 */
public class ApkUtil {
	public static final String VERSION_CODE = "versionCode";
	public static final String VERSION_NAME = "versionName";
	public static final String SDK_VERSION = "sdkVersion";
	public static final String TARGET_SDK_VERSION = "targetSdkVersion";
	public static final String USES_PERMISSION = "uses-permission";
	public static final String APPLICATION_LABEL = "application-label";
	public static final String APPLICATION_ICON = "application-icon";
	public static final String USES_FEATURE = "uses-feature";
	public static final String USES_IMPLIED_FEATURE = "uses-implied-feature";
	public static final String SUPPORTS_SCREENS = "supports-screens";
	public static final String SUPPORTS_ANY_DENSITY = "supports-any-density";
	public static final String DENSITIES = "densities";
	public static final String PACKAGE = "package";
	public static final String APPLICATION = "application:";
	public static final String LAUNCHABLE_ACTIVITY = "launchable-activity";
	public static final String APPLICATION_ICON_120 = "application-icon-120:";
	public static final String APPLICATION_ICON_160 = "application-icon-160:";
	public static final String APPLICATION_ICON_240 = "application-icon-240:";
	public static final String APPLICATION_ICON_320 = "application-icon-320:";
	public static final String APPLICATION_ICON_480 = "application-icon-480:";
	public static final String APPLICATION_ICON_640 = "application-icon-640:";

	private final ProcessBuilder mBuilder;
	private static final String SPLIT_REGEX = "(: )|(=')|(' )|'";
	private static final String FEATURE_SPLIT_REGEX = "(:')|(',')|'";
	/**
	 * aapt所在的目录。
	 */
	//windows环境下直接指向appt.exe
	//比如你可以放在src下
//	private static final String mAaptPath = "D:\\javaworkspace\\gitWorkSpace\\pangu-cloud\\pangu-upms\\pangu-upms-juhe-api\\src\\main\\resources\\aapt";
	//linux下
	private String mAaptPath = "/data/project/pythonWork/apktool/aapt";

	public ApkUtil() {
		mBuilder = new ProcessBuilder();
		mBuilder.redirectErrorStream(true);
	}

	/**
	 * 返回一个apk程序的信息。
	 *
	 * @param apkPath apk的路径。
	 * @return apkInfo 一个Apk的信息。
	 */
	public ApkInfo getApkInfo(String apkPath) throws Exception {
		System.out.println("================================开始执行命令=========================");
		//通过命令调用aapt工具解析apk文件
		Process process = mBuilder.command(mAaptPath, "d", "badging", apkPath)
				.start();
		InputStream is = null;
		is = process.getInputStream();
		BufferedReader br = new BufferedReader(
				new InputStreamReader(is, StandardCharsets.UTF_8));
		String tmp = br.readLine();
		try {
			if (tmp == null || !tmp.startsWith(PACKAGE)) {
				throw new Exception("参数不正确，无法正常解析APK包。输出结果为:" + tmp + "...");
			}
			ApkInfo apkInfo = new ApkInfo();
			do {
				setApkInfoProperty(apkInfo, tmp);
			} while ((tmp = br.readLine()) != null);
			return apkInfo;
		} catch (Exception e) {
			throw e;
		} finally {
			process.destroy();
			closeIO(is);
			closeIO(br);
		}
	}

	/**
	 * 设置APK的属性信息。
	 *
	 * @param apkInfo
	 * @param source
	 */
	private void setApkInfoProperty(ApkInfo apkInfo, String source) {
		System.out.println("source:"+ JSON.toJSONString(source));
		if (source.startsWith(PACKAGE)) {
			splitPackageInfo(apkInfo, source);
		} else if (source.startsWith(LAUNCHABLE_ACTIVITY)) {
			apkInfo.setLaunchableActivity(getPropertyInQuote(source));
		} else if (source.startsWith(SDK_VERSION)) {
			apkInfo.setSdkVersion(getPropertyInQuote(source));
		} else if (source.startsWith(TARGET_SDK_VERSION)) {
			apkInfo.setTargetSdkVersion(getPropertyInQuote(source));
		} else if (source.startsWith(APPLICATION_LABEL)) {
			//windows下获取应用名称
			apkInfo.setApplicationLable(getPropertyInQuote(source));
		} else if (source.startsWith(APPLICATION)) {
			String[] rs = source.split("( icon=')|'");
			apkInfo.setApplicationIcon(rs[rs.length - 1]);
			//linux下获取应用名称
			apkInfo.setApplicationLable(rs[1]);
		} else if (source.startsWith(APPLICATION_ICON_120)) {
			apkInfo.setApplicationIcon120(getPropertyInQuote(source));
		} else if (source.startsWith(APPLICATION_ICON_160)) {
			apkInfo.setApplicationIcon160(getPropertyInQuote(source));
		} else if (source.startsWith(APPLICATION_ICON_240)) {
			apkInfo.setApplicationIcon240(getPropertyInQuote(source));
		} else if (source.startsWith(APPLICATION_ICON_320)) {
			apkInfo.setApplicationIcon320(getPropertyInQuote(source));
		} else if (source.startsWith(APPLICATION_ICON_480)) {
			apkInfo.setApplicationIcon480(getPropertyInQuote(source));
		} else if (source.startsWith(APPLICATION_ICON_640)) {
			apkInfo.setApplicationIcon640(getPropertyInQuote(source));
		} else {
//       System.out.println(source);
		}
	}

	/**
	 * 返回出格式为name: 'value'中的value内容。
	 *
	 * @param source
	 * @return
	 */
	private String getPropertyInQuote(String source) {
		int index = source.indexOf("'") + 1;
		return source.substring(index, source.indexOf('\'', index));
	}

	/**
	 * 返回冒号前的属性名称
	 *
	 * @param source
	 * @return
	 */
	private String getKeyBeforeColon(String source) {
		return source.substring(0, source.indexOf(':'));
	}

	/**
	 * 分离出包名、版本等信息。
	 *
	 * @param apkInfo
	 * @param packageSource
	 */
	private void splitPackageInfo(ApkInfo apkInfo, String packageSource) {
		String[] packageInfo = packageSource.split(SPLIT_REGEX);
		apkInfo.setPackageName(packageInfo[2]);
		apkInfo.setVersionCode(packageInfo[4]);
		apkInfo.setVersionName(packageInfo[6]);
	}

	/**
	 * 释放资源。
	 *
	 * @param c 将关闭的资源
	 */
	private void closeIO(Closeable c) {
		if (c != null) {
			try {
				c.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public static Map readAPK(File file) {
		Map map = new HashMap<>();
		try {
			ApkFile apkFile = new ApkFile(file);
			ApkMeta apkMeta = apkFile.getApkMeta();
			map.put("appName", apkMeta.getLabel());
			map.put("packageName", apkMeta.getPackageName());
			map.put("versionCode", apkMeta.getVersionCode());
			map.put("versionName", apkMeta.getVersionName());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return map;
	}

	public static String generateFileName() {
		return DateUtil.getDates() + UUID.fastUUID().toString().replaceAll("-", "");
	}

	public static void main(String[] args) {
		try {
			String apkPath = "E:\\test\\demo02.apk";
			/*File file=new File(apkPath);
			System.out.println(readAPK(file));*/
			ApkInfo apkInfo = new ApkUtil().getApkInfo(apkPath);
			System.out.println(apkInfo);
			long now = System.currentTimeMillis();
			//判断下图片路径是否为png
			ApkIconUtil.extractFileFromApk(apkPath, apkInfo.getSuitableApplicationIcon(), "E:\\test\\" + now + ".png");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}
